﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using PSE.Tools.SchemaComparer.Comparer;
using PSE.Tools.SchemaComparer.Extractor;
using System.ComponentModel;
using System.IO;

namespace PSE.Tools.SchemaComparer.WindowsApp
{
    /// <summary>
    /// Interaction logic for UcComparer.xaml
    /// </summary>
    public partial class UcComparer : UserControl
    {
        public UcComparer()
        {
            InitializeComponent();
        }

        #region Compare
        public MainWindow ParentWindow;
        private DBSchemaCompareResult _compareResult;

        internal class CompareParameter
        {
            public string SourceSchemaFile
            {
                get;
                set;
            }

            public string TargetSchemaFile
            {
                get;
                set;
            }

            public string CompareResulFile
            {
                get;
                set;
            }
        }


        private void btnSchemaSource_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
            dialog.Filter = "Xml File |*.xml";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtSchemaSource.Text = dialog.FileName;
            }

        }

        private void btnSchemaTarget_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
            dialog.Filter = "Xml File |*.xml";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtSchemaTarget.Text = dialog.FileName;
            }
        }


        private void btnCompare_Click(object sender, RoutedEventArgs e)
        {
            CompareParameter parm = new CompareParameter();
            StringBuilder erroMessage = new StringBuilder();

            parm.SourceSchemaFile = txtSchemaSource.Text.Trim();
            parm.TargetSchemaFile = txtSchemaTarget.Text.Trim();
            parm.CompareResulFile = txtCompareFileResult.Text.Trim();

            if (string.IsNullOrEmpty(parm.SourceSchemaFile))
                erroMessage.AppendLine("- Schema 1 deve ser informado");

            if (string.IsNullOrEmpty(parm.TargetSchemaFile))
                erroMessage.AppendLine("- Schema 2 deve ser informado");

            if (string.IsNullOrEmpty(parm.CompareResulFile))
                erroMessage.AppendLine("- Arquivo de Saída deve ser informado");

            if (erroMessage.Length > 0)
            {
                MessageBox.Show(erroMessage.ToString());
                return;
            }

            ShowLoadingPanel("Comparando Schemas");

            BackgroundWorker bgCompare = new BackgroundWorker();
            bgCompare.DoWork += new DoWorkEventHandler(bgCompare_DoWork);
            bgCompare.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgCompare_RunWorkerCompleted);
            bgCompare.RunWorkerAsync(parm);
        }

        void bgCompare_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            HideLoadingPanel();

            if (_compareResult != null)
            {
                if (MessageBox.Show("Comparação de Schemas realizada com sucesso. Deseja visualizar o resultado da comparação?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    CompareResultView crView = new CompareResultView(_compareResult);
                    crView.Owner = this.ParentWindow;
                    crView.ShowDialog();
                }
            }
        }


        void bgCompare_DoWork(object sender, DoWorkEventArgs e)
        {
            CompareParameter parm = e.Argument as CompareParameter;
            DoCompare(parm.SourceSchemaFile, parm.TargetSchemaFile, parm.CompareResulFile);
        }


        private void DoCompare(string sourceSchemaFile, string targetSchemaFile, string compareResultFile)
        {
            bool error = false;

            StringBuilder sb = new StringBuilder();

            _compareResult = null;

            if (!File.Exists(sourceSchemaFile))
            {
                sb.Append(string.Format("- Arquivo {0} não encontrado", sourceSchemaFile));
            }

            if (!File.Exists(targetSchemaFile))
            {
                sb.Append(string.Format("- Arquivo {0} não encontrado", targetSchemaFile));
            }

            if (sb.Length > 0)
            {
                MessageBox.Show(sb.ToString());
                return;
            }


            DBSchema sourceSchema;
            try
            {
                sourceSchema = new DBSchema();
                sourceSchema.LoadFromXmlFile(sourceSchemaFile);

            }
            catch (Exception ex)
            {
                string message = string.Format("Erro ao carregar as informações de Schema do arquivo {0}.", sourceSchemaFile) + Environment.NewLine + ex.Message;
                EventLog.WriteEntry("SchemaComparer.Comparer", message, EventLogEntryType.Error);
                MessageBox.Show(message);
                return;
            }

            DBSchema targetSchema;
            try
            {
                targetSchema = new DBSchema();
                targetSchema.LoadFromXmlFile(targetSchemaFile);
            }
            catch (Exception ex)
            {
                string message = string.Format("Erro ao carregar as informações de Schema do arquivo {0}.", targetSchemaFile) + Environment.NewLine + ex.Message;
                EventLog.WriteEntry("SchemaComparer.Comparer", message, EventLogEntryType.Error);
                MessageBox.Show(message);
                return;

            }

            DBSchemaComparer schemaComparer;
            try
            {
                schemaComparer = new DBSchemaComparer();
                _compareResult = schemaComparer.Compare(sourceSchema, targetSchema);
            }
            catch (Exception ex)
            {
                string message = "Erro ao comparar as informações dos Schemas." + Environment.NewLine + ex.Message;
                EventLog.WriteEntry("SchemaComparer.Comparer", message, EventLogEntryType.Error);
                MessageBox.Show(message);
                return;
            }

            try
            {
                schemaComparer.SaveCompareResultToXmlFile(compareResultFile);
            }
            catch (Exception ex)
            {
                string message = "Erro ao salvar o resultado da comparação dos Schemas." + Environment.NewLine + ex.Message;
                EventLog.WriteEntry("SchemaComparer.Comparer", message, EventLogEntryType.Error);
                MessageBox.Show(message);
                return;
            }

        }
        private void btnCompareFileResult_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.Filter = "Xml File |*.xml";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtCompareFileResult.Text = dialog.FileName;
            }
        }


        private void ShowLoadingPanel(string text)
        {
            if (ParentWindow != null)
                ParentWindow.ShowLoadingPanel(text);
        }

        private void HideLoadingPanel()
        {
            if (ParentWindow != null)
                ParentWindow.HideLoadingPanel();
        }
        #endregion
    }
}
